<template>
  <div class="__layout-aside" :class="{ collapsed: isCollapsed }">
    <div class="title">
      <img src="@/assets/image/layout/rich.png" class="title-icon" />
      <span class="title-text">慢慢变富</span>
    </div>
    <div class="menu-container">
      <router-link
        v-for="menu in filteredMenus"
        :key="menu.path"
        :to="menu.path"
        class="menu-item"
        :class="{ 'menu-item-active': isActive(menu.path) }"
      >
        <el-icon class="menu-icon"><Apple /></el-icon>
        <span class="menu-text">{{ menu.name }}</span>
      </router-link>
    </div>
    <footer class="aside-footer">
      <button class="toggle-btn" :aria-expanded="!isCollapsed" @click="isCollapsed = !isCollapsed">
        <el-icon class="toggle-icon">
          <Expand v-if="isCollapsed" />
          <Fold v-else />
        </el-icon>
        <span class="toggle-text">{{ isCollapsed ? '展开导航' : '收起导航' }}</span>
      </button>
    </footer>
  </div>
</template>

<script setup lang="ts">
import { useRouter, useRoute } from 'vue-router'
import { computed, ref, watch } from 'vue'
import { Apple, Expand, Fold } from '@element-plus/icons-vue'

// 路由和导航
const router = useRouter()
const route = useRoute()

// 导航收起/展开状态（默认展开）
const isCollapsed = ref(false)

// 定义路由项和菜单项的类型
type RouteItem = {
  path: string
  meta?: {
    title?: string
    showInMenu?: boolean
  }
  children?: RouteItem[]
}

type MenuItem = {
  name: string
  path: string
  meta?: RouteItem['meta']
  children: MenuItem[]
}

// 从路由配置中获取菜单项
const allMenus = computed(() => {
  // 递归处理菜单结构
  const processRoutes = (routes: RouteItem[]): MenuItem[] => {
    return routes
      .filter((route) => route.meta?.title && route.meta?.showInMenu !== false)
      .map((route) => ({
        name: route.meta?.title || '未命名',
        path: route.path as string,
        meta: route.meta,
        // 处理二级菜单（递归处理）
        children: route.children ? processRoutes(route.children) : [],
      }))
  }

  // 根据提供的路由结构，直接处理根路由的children
  return processRoutes(router.options.routes.flatMap((route) => route.children || []))
})

// 过滤后的菜单项（排除不需要显示的）
const filteredMenus = computed(() => {
  return allMenus.value.filter((menu) => menu.meta?.showInMenu !== false)
})

// 使用 watch 监听路由变化，更新当前匹配的路径数组
const matchedPaths = ref<string[]>([])
const matchedTitles = ref<string[]>([])
watch(
  () => route.matched,
  (matched) => {
    matchedPaths.value = matched.map((item) => item.path)
    // 过滤title为空
    matchedTitles.value = matched
      .map((item) => (item.meta?.title as string) || '')
      .filter((title) => title !== '')
  },
  { immediate: true },
)

// 优化后的 isActive 方法，直接使用缓存的匹配路径数组
const isActive = (path: string) => {
  return matchedPaths.value.includes(path) || (path === '/' && matchedPaths.value.includes('/'))
}
</script>

<style lang="scss" scoped>
.__layout-aside {
  width: 250px;
  height: 100%;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 50px 1fr 40px;
  grid-column-gap: 16px;
  grid-row-gap: 16px;
  transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); // 使用更平滑的缓动函数

  // 收起状态的样式
  &.collapsed {
    width: 80px;
  }

  .title {
    height: 60px;
    width: 100%;
    font-size: 20px;
    font-weight: 400;
    color: #2f3135;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;

    transition:
      justify-content 0.3s ease,
      padding 0.3s ease;

    .title-icon {
      width: 36px;
      height: 36px;
    }

    .title-text {
      white-space: nowrap; // 防止文字换行
      transition:
        opacity 0.3s ease,
        transform 0.3s ease,
        width 0.3s ease;
      transform-origin: left center; // 设置变换原点
    }
  }

  .menu-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;

    .menu-item {
      width: calc(100% - 32px);
      padding: 0 16px;
      height: 40px;
      color: #35404f;
      cursor: pointer;
      text-decoration: none;
      display: flex;
      gap: 8px;
      align-items: center;
      transition:
        transform 0.2s ease,
        justify-content 0.3s ease,
        width 0.3s ease,
        padding 0.3s ease;

      &:hover {
        transform: translateY(-2px);
      }

      .menu-icon {
        width: 20px;
        height: 20px;
      }

      .menu-text {
        white-space: nowrap; // 防止文字换行
        transition:
          opacity 0.3s ease,
          transform 0.3s ease,
          width 0.3s ease;
        transform-origin: left center; // 设置变换原点
      }
    }

    .menu-item-active {
      color: #2262fb;
      border-radius: 8px;
      background: rgba(255, 255, 255, 1);
    }
  }

  .aside-footer {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0 16px;

    .toggle-btn {
      width: 100%;
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 6px 12px;
      border: none;
      background: #f5f7fa;
      border-radius: 6px;
      cursor: pointer;
      color: #35404f;
      transition: all 0.2s;

      &:hover {
        background: #e8ebf0;
      }

      .toggle-icon {
        width: 16px;
        height: 16px;
      }

      .toggle-text {
        white-space: nowrap; // 防止文字换行
        transition:
          opacity 0.3s ease,
          transform 0.3s ease,
          width 0.3s ease;
        font-size: 14px;
        transform-origin: left center; // 设置变换原点
      }
    }
  }

  // 收起状态下隐藏所有文字元素（优化动画）
  &.collapsed {
    .title {
      justify-content: center;
      padding-left: 0;

      .title-text {
        opacity: 0;
        transform: scaleX(0); // 使用缩放代替位移，更平滑
        width: 0; // 收缩宽度
      }
    }

    .menu-item {
      justify-content: center;
      width: 100%;
      padding: 0;

      .menu-text {
        opacity: 0;
        transform: scaleX(0); // 使用缩放代替位移
        width: 0; // 收缩宽度
      }
    }

    .aside-footer {
      .toggle-btn {
        .toggle-text {
          opacity: 0;
          transform: scaleX(0); // 使用缩放代替位移
          width: 0; // 收缩宽度
        }
      }
    }
  }
}
</style>
